package jast;
import java.util.ArrayList;

import path.BranchNode;
import path.PathRec;
import path.SwitchBranchNode;

public class PathGen {
	private ArrayList<PathRec> pathList = new ArrayList<PathRec>();
	private BranchNode startNode;
	private BranchNode exitNode;
	/**
	 * 
	 * @param start 程序流图开始节点
	 * @param exit 程序流图结束节点
	 */
	public PathGen(BranchNode start, BranchNode exit){
		this.startNode = start;
		this.exitNode = exit;
	}
	/**
	 * 分析程序流图得到基本路径集合
	 * @param start 程序流图开始节点
	 * @param exit 程序流图结束节点
	 * @return 基本路径集合
	 */
	public ArrayList<PathRec> getPrimePathList(BranchNode start, BranchNode exit){
		startNode = start;
		exitNode = exit;
		return getPrimePathList();
	}
	/**
	 * 分析程序流图得到基本路径集合
	 * @return 基本路径集合
	 */
	public ArrayList<PathRec> getPrimePathList(){
		PathRec pr = new PathRec();
		if(startNode != null && exitNode != null){
			pathList.clear();
			visitPrimePath(startNode, pr);
			return pathList;
		}else
			return null;
	}
	
	/**
	 * 基本路径集合
	 * @param next
	 * @param pr
	 */
	private void visitPrimePath(BranchNode next, PathRec pr){
		if(next.equals(exitNode)){
			pathList.add(pr);
			return;
		}
		//判断是否遍历过
		if(next.visited){
			// 加入路径
			if(next.branchNum != -1){
				pr.path.add(next);
			}
			if(next.type == 2)
				visitPrimePath(next.exitNode, pr);
			else if (next.type == 3)
				visitPrimePath(((SwitchBranchNode)next).caseList.get(0), pr.copy());
			else{// (next.getLeft() != null && next.getRight() != null),next.getRight() == null
				if(next.getLeft() != null)
					visitPrimePath(next.getLeft(), pr.copy());//已遍历过，只走一个分支继续
				else
					visitPrimePath(next.getRight(), pr.copy());
			}
		}else{
			// 加入路径
			if(next.branchNum != -1){
				pr.path.add(next);
			}
			next.visited = true;
			if (next.type == 3)
				for (int i = 0; i < ((SwitchBranchNode)next).caseList.size(); i++) {
					visitPrimePath(((SwitchBranchNode)next).caseList.get(i), pr.copy());
				}
			else{
				if (next.getLeft() != null) {
					visitPrimePath(next.getLeft(), pr.copy());
				}
				if (next.getRight() != null) {
					visitPrimePath(next.getRight(), pr.copy());
				}
			}
		}
	}
}